﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System;
using System.IO.Ports;
using DidaManager.Log;

namespace DidaManager.Native.RemoteTransmission
{

    public class TransSerialPortHandler
    {
        public delegate void DataReceivedHandler(byte[] buffer, int offset, int count);
        public event DataReceivedHandler? DataReceived;

        private System.IO.Ports.SerialPort _serialPort;

        public TransSerialPortHandler()
        {
            _serialPort = new System.IO.Ports.SerialPort();
        }

        public void Initialize(string portName, string baudRate, string dataBits, string stopBits, string parity)
        {
            int baudRateInt = int.Parse(baudRate);
            int dataBitsInt = int.Parse(dataBits);

            StopBits stopBitsEnum = (StopBits)Enum.Parse(typeof(StopBits), stopBits);
            Parity parityEnum = (Parity)Enum.Parse(typeof(Parity), parity);

            _serialPort.PortName = portName;
            _serialPort.BaudRate = baudRateInt;
            _serialPort.DataBits = dataBitsInt;
            _serialPort.StopBits = stopBitsEnum;
            _serialPort.Parity = parityEnum;

            _serialPort.DataReceived += SerialPortDataReceived;
        }

        private void SerialPortDataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            System.IO.Ports.SerialPort sp = (System.IO.Ports.SerialPort)sender;
            // 定义一个缓冲区来存储读取的数据
            byte[] buffer = new byte[sp.BytesToRead];

            // 从串口读取数据到缓冲区中
            int bytesRead = sp.Read(buffer, 0, buffer.Length);
            string hexString = BitConverter.ToString(buffer, 0, buffer.Length).Replace("-", " ");
            LogManager.Debug("serial port read  length: " + buffer.Length);
            LogManager.Debug("serial port read  hex data : " + hexString);

            DataReceived?.Invoke(buffer,0,buffer.Length);
        }

        public bool Open()
        {
            if (!_serialPort.IsOpen)
            {
                try
                {
                    _serialPort.Open();
                   LogManager.Debug("Serial port opened");
                    return true;
                }
                catch (Exception ex)
                {
                   LogManager.Debug("Error opening serial port: " + ex.Message);
                    return false;
                }
            }
            return true; // Port is already open
        }

        public void Close()
        {
            if (_serialPort.IsOpen)
            {
                _serialPort.Close();
                LogManager.Debug("Serial port closed");
            }
        }

        public void Write(string data)
        {
            bool bRet = RspTransWebsocketData.CheckForCodeAndMessage(data);
            if (bRet)// 是返回应答状态，不是数据
            {
                LogManager.Warn("serialport recv not valid data: " + data);
                return;
            }
            if (_serialPort.IsOpen)
            {
                DirectData? temp = DirectData.FromJson(data);
                byte[] buffer = Convert.FromBase64String(temp?.Data ?? "");
                if (temp?.DataLen != buffer.Length)
                {
                    Array.Clear(buffer, 0, buffer.Length);
                    buffer = Convert.FromHexString(temp?.Data ?? "");
                }
                string hexString = BitConverter.ToString(buffer, 0, buffer.Length).Replace("-", " ");
                LogManager.Debug("serial port write  length: " + buffer.Length);
                LogManager.Debug("serial port write  hex data : " + hexString);

                _serialPort.Write(buffer,0,buffer.Length);
            }
            else
            {
               LogManager.Warn("Serial port is not open");
            }
        }

        public void WriteRaw(string data)
        {
            if (_serialPort.IsOpen)
            {
                _serialPort.Write(data);
            }
        }

            public bool IsOpen()
        {
            return _serialPort.IsOpen;
        }
    }

}
